/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.gen.seam.generator.template;

import br.gen.seam.generator.Configuration;
import br.gen.seam.generator.SeamGenerator;
import br.gen.seam.util.StringUtil;
import br.gen.seam.util.entity.Column;
import br.gen.seam.util.entity.Constraint;
import br.gen.seam.util.entity.Table;
import br.gen.seam.util.entity.Type;
import br.gen.seam.util.exception.UtilException;

/**
 *
 * @author Gustavo
 */
public class EntityTemplate extends Template {

    private StringBuffer entity = new StringBuffer();

    private StringBuffer importsEntities = new StringBuffer();

    @Override
    public void generate() {
        init();
        generateColumns();
        generateGetsAndSets();
        generateEquals();
        generateHashCode();
    }

    private void init(){
        entity.append("import java.io.Serializable;\n")
              .append("import javax.persistence.Column;\n")
              .append("import javax.persistence.Entity;\n")
              .append("import javax.persistence.Table;\n")
              .append("${imports.class}")
              .append("\n")
              .append("@Entity\n")
              .append("@Table(name=\"").append(getTable().getName()).append("\", schema=\"").append(getTable().getSchema()).append("\")\n")
              .append("public class ").append(getTable().getName()).append(" implements Serializable {\n\n")
              .append("private static final long serialVersionUID = 1L;\n\n");
    }

    private void generateColumns() {
        for (Column column : getTable().getColumns()) {
            generateColumn(column);
        }
    }

    private void generateColumn(Column column) {
        if(column.getConstraint() != null &&
                (column.getConstraint().equals(Constraint.PRIMARY_KEY) ||
                column.getConstraint().equals(Constraint.PK_FK_KEY))) {
            importsEntities.append("import javax.persistence.Id;\n")
                    .append("import javax.persistence.GeneratedValue;\n");
            entity.append("@Id\n")
                .append("@GeneratedValue\n");
        } else if(column.getConstraint() != null && column.getConstraint().equals(Constraint.UNIQUE)) {
            importsEntities.append("import javax.persistence.Unique;\n");
            entity.append("@Unique\n");
        }
        entity.append("@Column(name = \"").append(column.getName())
                .append("\", nullable = ").append(column.isNullable())
                .append(", length = 0)\n")
                .append(generateTypeColumn(column));
    }

    private String generateTypeColumn(Column column){
        String typeColumn = "";
        if(column.getConstraint() != null && 
                (column.getConstraint().equals(Constraint.FOREING_KEY) ||
                column.getConstraint().equals(Constraint.PK_FK_KEY))) {
            try {
                String columnName = StringUtil.convertToPatternAttributeName(column.getName(), "[_]");
                Table table = column.getConstraint().getColumn().getTable();


                Configuration configuration = Configuration.getCurrentInstance();
                SeamGenerator generator = new SeamGenerator();
                generator.mountPackageNames(table, configuration.getPackageBean(),
                        configuration.getPackageDao(),
                        configuration.getPackageEntity());

                String className = StringUtil.convertToPatternClassName(table.getName(), "[_]");

                importsEntities.append("import "+ table.getPackageNameEntity() +"."+ className +";\n");

                column.setType(new Type(className));

                typeColumn = "private " + className + " " + columnName;
            } catch (UtilException ex) {
                ex.printStackTrace();
            }
        } else {
            typeColumn = "private " + column.getType() + " " + column.getName();

            if(column.getType().toString().equals("Long")){
                typeColumn += " = Long.valueOf(0);";
            } else if (column.getType().toString().equals("String")) {
                typeColumn += " = \"\";";
            } else if (column.getType().toString().equals("Boolean")) {
                typeColumn += " = Boolean.FALSE;";
            } else if (column.getType().toString().equals("BigDecimal")) {
                typeColumn += " = new BigDecimal(0);";
                importsEntities.append("import java.math.BigDecimal;\n");
            } else if (column.getType().toString().equals("Date")) {
                typeColumn += " = new Date();";
                importsEntities.append("import java.util.Date;\n");
            } else {
                typeColumn += ";";
            }
        }

        return typeColumn + "\n\n";
    }

    private void generateGetsAndSets(){
        for (Column column : getTable().getColumns()) {
            generateGetAndSet(column);
        }
    }

    private void generateGetAndSet(Column column){

        char firstChar = column.getName().charAt(0);
        String newColumnName = Character.toUpperCase(firstChar) + column.getName().substring(1);

        StringBuffer getNSet = new StringBuffer("public ")
                    .append(column.getType() + " get" +newColumnName + "{\n")
                    .append("return this.").append(column.getName())
                    .append(";\n}\n")

                    .append("public void set" + newColumnName + "("+column.getType()+ " "+ column.getName()+"){\n")
                    .append("this." + column.getName() + " = " + column.getName())
                    .append(";\n}\n");

        entity.append(getNSet);
    }

    private void generateEquals(){
        StringBuffer equals = new StringBuffer("@Override\n")
                     .append("public boolean equals(Object object) {\n")
                     .append("if (object == null || !this.getClass().equals(object.getClass())) {\n")
                     .append("return false;\n")
                     .append("}\n return true; \n}\n");

        entity.append(equals);
    }
    
    private void generateHashCode(){

        StringBuffer hashCode = new StringBuffer("@Override\n")
                     .append("public int hashCode() {\n")
                     .append("final int prime = 31;\n")
                     .append("int result = 1;\n")
                     .append("result = prime * result + ((id == null) ? 0 : id.hashCode());\n")
                     .append("return result;\n}\n}\n");

        entity.append(hashCode);
	
    }

    @Override
    public String toString() {
        return entity.toString().replace("${imports.class}", importsEntities.toString());
    }
}
